package com.szzg10.webservice.chapter4;

import java.io.ByteArrayInputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

public class RabbitCountProviderClient {

	public static void main(String[] args) throws XPathExpressionException, URISyntaxException, TransformerFactoryConfigurationError, TransformerException {
		new RabbitCountProviderClient().doIt();
	}
	
	private void doIt() throws URISyntaxException, XPathExpressionException, TransformerFactoryConfigurationError, TransformerException {
		URI uri = new URI("urn:fib");
		
		QName serviceName = new QName("rcService", uri.toString());
		QName portName = new QName("rcPort", uri.toString());
		String endpointAddress = "http://localhost:9876/rabbitCountProvider";
		
		Service service = Service.create(serviceName);
		service.addPort(portName, HTTPBinding.HTTP_BINDING, endpointAddress);
		
		Dispatch<Source> dispatch = service.createDispatch(portName, Source.class, Service.Mode.PAYLOAD);
		
		String xml_start = "<fib:request xmlns:fib='urn:fib'>";
		String xml_end = "</fib:request>";
		
		//---POST---
		List<Integer> list = new ArrayList<Integer>();
		for(int i = 0; i < 10; i++) {
			list.add(i);
		}
		
		String content = list.toString();
		String text = xml_start + content + xml_end;
		invoke(dispatch, "POST", uri.toString(), text);
		
		//---GET---
		invoke(dispatch, "GET", uri.toString(), null);
		
		//---DELETE---
		invoke(dispatch, "DELETE", uri.toString(), null);
		
		//---POST---
		invoke(dispatch, "POST", uri.toString(), text);
		
		//--GET---
		invoke(dispatch, "GET", uri.toString(), null);
	}
	
	private void invoke(Dispatch<Source> dispatch, String verb, String uri, String text) 
			throws XPathExpressionException, TransformerFactoryConfigurationError, TransformerException {
		
		Map<String, Object> requestContext = dispatch.getRequestContext();
		requestContext.put(MessageContext.HTTP_REQUEST_METHOD, verb);
		
		StreamSource streamSource = null;
		if(text != null) {
			streamSource = make_stream_source(text);
		}
		Source result = dispatch.invoke(streamSource);
		
		display_result(result, uri);
	}
	
	private StreamSource make_stream_source(String text) {
		byte[] bytes = text.getBytes();
		ByteArrayInputStream in = new ByteArrayInputStream(bytes);
		
		return new StreamSource(in);
	}
	
	private void display_result(Source source, final String uri) throws TransformerFactoryConfigurationError, TransformerException, XPathExpressionException {
		DOMResult domResult = new DOMResult();
		
		Transformer transformer = TransformerFactory.newInstance().newTransformer();
		transformer.transform(source, domResult);
		
		XPath xPath = XPathFactory.newInstance().newXPath();
		xPath.setNamespaceContext(new NamespaceContext() {
			
			@Override
			public Iterator getPrefixes(String arg0) {
				return null;
			}
			
			@Override
			public String getPrefix(String arg0) {
				return uri;
			}
			
			@Override
			public String getNamespaceURI(String arg0) {
				return uri;
			}
		});
		
		String result = xPath.evaluate("/fib:response", domResult.getNode());
		System.out.println(result);
	}
	
}
